{
return
mode == OSTREE_REPO_MODE_BARE ||
- mode == OSTREE_REPO_MODE_BARE_USER;
+ mode == OSTREE_REPO_MODE_BARE_USER ||
+ mode == OSTREE_REPO_MODE_BARE_USER_ONLY;
}
GVariant *
* @OSTREE_REPO_MODE_BARE: Files are stored as themselves; checkouts are hardlinks; can only be written as root
* @OSTREE_REPO_MODE_ARCHIVE_Z2: Files are compressed, should be owned by non-root. Can be served via HTTP
* @OSTREE_REPO_MODE_BARE_USER: Files are stored as themselves, except ownership; can be written by user. Hardlinks work only in user checkouts.
+ * @OSTREE_REPO_MODE_BARE_USER_ONLY: Same as BARE_USER, but all metadata is not stored, so it can only be used for user checkouts. Does not need xattrs.
*
* See the documentation of #OstreeRepo for more information about the
* possible modes.
typedef enum {
OSTREE_REPO_MODE_BARE,
OSTREE_REPO_MODE_ARCHIVE_Z2,
- OSTREE_REPO_MODE_BARE_USER
+ OSTREE_REPO_MODE_BARE_USER,
+ OSTREE_REPO_MODE_BARE_USER_ONLY,
} OstreeRepoMode;
_OSTREE_PUBLIC
(current_repo->mode == OSTREE_REPO_MODE_BARE_USER
&& options->mode == OSTREE_REPO_CHECKOUT_MODE_USER
/* NOTE: bare-user symlinks are not stored as symlinks */
- && !is_symlink));
+ && !is_symlink) ||
+ (current_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY
+ && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER));
gboolean current_can_cache = (options->enable_uncompressed_cache
&& current_repo->enable_uncompressed_cache);
gboolean is_archive_z2_with_cache = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
{
OstreeRepoCheckoutAtOptions options = { 0, };
+ if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ mode = OSTREE_REPO_CHECKOUT_MODE_USER;
+
options.mode = mode;
options.overwrite_mode = overwrite_mode;
/* Backwards compatibility */
GError **error)
{
OstreeRepoCheckoutAtOptions default_options = { 0, };
+ OstreeRepoCheckoutAtOptions real_options;
if (!options)
{
options = &default_options;
}
+ /* Make a copy so we can modify the options */
+ real_options = *options;
+ options = &real_options;
+
+ if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ options->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
+
g_autoptr(GFile) commit_root = (GFile*) _ostree_repo_file_new_for_commit (self, commit, error);
if (!commit_root)
return FALSE;
}
/* Special handling for symlinks in bare repositories */
- if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE)
+ if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ {
+ /* We don't store the metadata in bare-user-only, so we're done. */
+ }
+ else if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE)
{
/* Now that we know the checksum is valid, apply uid/gid, mode bits,
* and extended attributes.
}
}
- if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE_USER)
+ if (objtype == OSTREE_OBJECT_TYPE_FILE &&
+ (self->mode == OSTREE_REPO_MODE_BARE_USER || self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY))
{
if (!object_is_symlink)
{
}
}
- if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
+ if (self->mode == OSTREE_REPO_MODE_BARE_USER &&
+ !write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
goto out;
}
cancellable, error))
goto out;
}
- else if (repo_mode == OSTREE_REPO_MODE_BARE && temp_file_is_symlink)
+ else if (_ostree_repo_mode_is_bare (repo_mode) && temp_file_is_symlink)
{
+ /* Note: This will not be hit for bare-user mode because its converted to a
+ regular file and take the branch above */
if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd,
g_file_info_get_symlink_target (file_info),
&temp_filename,
case OSTREE_REPO_MODE_ARCHIVE_Z2:
case OSTREE_REPO_MODE_BARE:
case OSTREE_REPO_MODE_BARE_USER:
+ case OSTREE_REPO_MODE_BARE_USER_ONLY:
skip = !g_str_has_suffix (name, ".file");
break;
default:
case OSTREE_REPO_MODE_BARE_USER:
ret_mode = "bare-user";
break;
+ case OSTREE_REPO_MODE_BARE_USER_ONLY:
+ ret_mode = "bare-user-only";
+ break;
case OSTREE_REPO_MODE_ARCHIVE_Z2:
ret_mode ="archive-z2";
break;
ret_mode = OSTREE_REPO_MODE_BARE;
else if (strcmp (mode, "bare-user") == 0)
ret_mode = OSTREE_REPO_MODE_BARE_USER;
+ else if (strcmp (mode, "bare-user-only") == 0)
+ ret_mode = OSTREE_REPO_MODE_BARE_USER_ONLY;
else if (strcmp (mode, "archive-z2") == 0 ||
strcmp (mode, "archive") == 0)
ret_mode = OSTREE_REPO_MODE_ARCHIVE_Z2;
g_file_info_set_symlink_target (ret_file_info, targetbuf);
}
}
+ else if (repo_mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ {
+ glnx_fd_close int fd = -1;
+
+ /* Canonical info is: uid/gid is 0 and no xattrs, which
+ might be wrong and thus not validate correctly, but
+ at least we report something consistent. */
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", 0);
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", 0);
+
+ if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR &&
+ out_input)
+ {
+ fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ {
+ glnx_set_error_from_errno (error);
+ goto out;
+ }
+
+ ret_input = g_unix_input_stream_new (fd, TRUE);
+ fd = -1; /* Transfer ownership */
+ }
+
+ if (out_xattrs)
+ {
+ GVariantBuilder builder;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
+ ret_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder));
+ }
+ }
else
{
g_assert (repo_mode == OSTREE_REPO_MODE_BARE);